{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![image](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://demo.leafmap.org/lab/index.html?path=notebooks/94_mapbox.ipynb)\n",
    "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/opengeos/leafmap/blob/master/docs/notebooks/94_mapbox.ipynb)\n",
    "[![image](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/opengeos/leafmap/HEAD)\n",
    "\n",
    "**Creating 3D maps with Mapbox**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %pip install -U leafmap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import leafmap.mapbox as leafmap"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You need a Mapbox access token to use the Mapbox widget. First, [sign up](https://account.mapbox.com/auth/signup/) for a free Mapbox account. Then, you can create a token by following the instructions [here](https://docs.mapbox.com/api/accounts/tokens/). Set `Mapbox_TOKEN` as an environment variable to use the Mapbox widget. Alternatively, uncomment the following code block and replace `YOUR-API-TOKEN` with your Mapbox access token."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import os\n",
    "# os.environ['MAPBOX_TOKEN'] = 'YOUR-API-TOKEN'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = leafmap.Map(center=[-100, 40], zoom=1.2, height=\"600px\")\n",
    "m"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://i.imgur.com/1PbtnQE.gif)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = leafmap.Map(style=\"mapbox://styles/mapbox/satellite-streets-v12\")\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.clicked_lnglat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.zoom"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.center"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.bounds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "esm = \"\"\"\n",
    "\n",
    "    const map = new mapboxgl.Map({\n",
    "        container: 'map',\n",
    "        zoom: 14,\n",
    "        center: [-114.26608, 32.7213],\n",
    "        pitch: 80,\n",
    "        bearing: 41,\n",
    "        // Choose from Mapbox's core styles, or make your own style with Mapbox Studio\n",
    "        style: 'mapbox://styles/mapbox/satellite-streets-v12'\n",
    "    });\n",
    "\n",
    "    map.on('style.load', () => {\n",
    "        map.addSource('mapbox-dem', {\n",
    "            'type': 'raster-dem',\n",
    "            'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',\n",
    "            'tileSize': 512,\n",
    "            'maxzoom': 14\n",
    "        });\n",
    "        // add the DEM source as a terrain layer with exaggerated height\n",
    "        map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 });\n",
    "    });\n",
    "\n",
    "\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.set_esm(esm)\n",
    "m"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://i.imgur.com/xvdrvpx.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "esm = \"\"\"\n",
    "\n",
    "    (async () => {\n",
    "        const map = new mapboxgl.Map({\n",
    "            container: 'map',\n",
    "            zoom: 13,\n",
    "            center: [6.6301, 45.35625],\n",
    "            pitch: 80,\n",
    "            bearing: 160,\n",
    "            interactive: false,\n",
    "            // Choose from Mapbox's core styles, or make your own style with Mapbox Studio\n",
    "            style: 'mapbox://styles/mapbox/satellite-v9'\n",
    "        });\n",
    "\n",
    "        await map.once('style.load');\n",
    "\n",
    "        // Add daytime fog\n",
    "        map.setFog({\n",
    "            'range': [-1, 2],\n",
    "            'horizon-blend': 0.3,\n",
    "            'color': 'white',\n",
    "            'high-color': '#add8e6',\n",
    "            'space-color': '#d8f2ff',\n",
    "            'star-intensity': 0.0\n",
    "        });\n",
    "\n",
    "        // Add 3D terrain\n",
    "        map.addSource('mapbox-dem', {\n",
    "            'type': 'raster-dem',\n",
    "            'url': 'mapbox://mapbox.terrain-rgb',\n",
    "            'tileSize': 512,\n",
    "            'maxzoom': 14\n",
    "        });\n",
    "        map.setTerrain({\n",
    "            'source': 'mapbox-dem',\n",
    "            'exaggeration': 1.5\n",
    "        });\n",
    "\n",
    "        // Run a timing loop to switch between day and night\n",
    "        await map.once('idle');\n",
    "\n",
    "        let lastTime = 0.0;\n",
    "        let animationTime = 0.0;\n",
    "        let cycleTime = 0.0;\n",
    "        let night = true;\n",
    "\n",
    "        const initialBearing = map.getBearing();\n",
    "\n",
    "        function frame(time) {\n",
    "            const elapsedTime = (time - lastTime) / 1000.0;\n",
    "\n",
    "            animationTime += elapsedTime;\n",
    "            cycleTime += elapsedTime;\n",
    "\n",
    "            if (cycleTime >= 10.0) {\n",
    "                if (night) {\n",
    "                    // night fog styling\n",
    "                    map.setFog({\n",
    "                        'range': [-1, 2],\n",
    "                        'horizon-blend': 0.3,\n",
    "                        'color': '#242B4B',\n",
    "                        'high-color': '#161B36',\n",
    "                        'space-color': '#0B1026',\n",
    "                        'star-intensity': 0.8\n",
    "                    });\n",
    "                } else {\n",
    "                    // day fog styling\n",
    "                    map.setFog({\n",
    "                        'range': [-1, 2],\n",
    "                        'horizon-blend': 0.3,\n",
    "                        'color': 'white',\n",
    "                        'high-color': '#add8e6',\n",
    "                        'space-color': '#d8f2ff',\n",
    "                        'star-intensity': 0.0\n",
    "                    });\n",
    "                }\n",
    "\n",
    "                night = !night;\n",
    "                cycleTime = 0.0;\n",
    "            }\n",
    "\n",
    "            const rotation = initialBearing + animationTime * 2.0;\n",
    "            map.setBearing(rotation % 360);\n",
    "\n",
    "            lastTime = time;\n",
    "\n",
    "            window.requestAnimationFrame(frame);\n",
    "        }\n",
    "\n",
    "        window.requestAnimationFrame(frame);\n",
    "    })();\n",
    "\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.set_esm(esm)\n",
    "m"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://i.imgur.com/ZRRUK3v.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = leafmap.Map(style=\"mapbox://styles/mapbox/satellite-streets-v12\")\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import ee\n",
    "# ee.Authenticate()\n",
    "# ee.Initialize(project=\"YOUR-PROJECT-ID\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dataset = ee.ImageCollection(\"ESA/WorldCover/v200\").first()\n",
    "# vis_params = {\"bands\": [\"Map\"]}\n",
    "# url = leafmap.ee_tile_url(dataset, vis_params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "esm = \"\"\"\n",
    "    const map = new mapboxgl.Map({\n",
    "        container: 'map',\n",
    "        zoom: 1.2,\n",
    "        center: [-100, 40],\n",
    "        // Choose from Mapbox's core styles, or make your own style with Mapbox Studio\n",
    "        style: 'mapbox://styles/mapbox/satellite-streets-v12'\n",
    "    });\n",
    "\n",
    "    map.on('style.load', () => {\n",
    "        map.addSource('mapbox-dem', {\n",
    "            'type': 'raster-dem',\n",
    "            'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',\n",
    "            'tileSize': 512,\n",
    "            'maxzoom': 14\n",
    "        });\n",
    "        // add the DEM source as a terrain layer with exaggerated height\n",
    "        map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 });\n",
    "\n",
    "        map.addSource('raster-tiles', {\n",
    "            'type': 'raster',\n",
    "            'tiles': [\n",
    "                'https://THE-TILE-URL' // replace with the actual tile URL\n",
    "            ],\n",
    "            'tileSize': 256\n",
    "        });\n",
    "\n",
    "        map.addLayer({\n",
    "            'id': 'raster-layer',\n",
    "            'type': 'raster',\n",
    "            'source': 'raster-tiles',\n",
    "            'paint': {\n",
    "                'raster-opacity': 0.7 // Adjust the opacity as needed\n",
    "            }\n",
    "        });\n",
    "        \n",
    "    });\n",
    "\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.set_esm(esm)\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://i.imgur.com/8YXh4Cv.png)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
